﻿// <copyright file="TrackApplication.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2010-02-15</date>
// <summary>TrackApplication class definition</summary>

namespace Microsoft.WebAnalytics.Behaviors
{
    using System;
    using System.ComponentModel.Composition;
    using System.Windows;
    using System.Windows.Interactivity;

    /// <summary>
    /// Track WPF Startup, Navigated, FragmentNavigation, and Exit events
    /// </summary>
    public class TrackApplication : Behavior<FrameworkElement>
    {
        /// <summary>
        /// Gets or sets the event Logging method
        /// </summary>
        [Import("Log")]
        public Action<AnalyticsEvent> Log { get; set; }

        /// <summary>
        /// Attach the events
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();

            PartInitializer.SatisfyImports(this);

            Application.Current.Exit += new ExitEventHandler(this.OnExit);
            Application.Current.FragmentNavigation += new System.Windows.Navigation.FragmentNavigationEventHandler(this.FragmentNavigation);
            Application.Current.Navigated += new System.Windows.Navigation.NavigatedEventHandler(this.Navigated);
            Application.Current.Startup += new StartupEventHandler(this.Startup);

            this.AssociatedObject.Unloaded += new RoutedEventHandler(delegate(object sender, RoutedEventArgs args)
            {
                System.Windows.Interactivity.Interaction.GetBehaviors(this.AssociatedObject).Remove(this);
            });
        }

        /// <summary>
        /// Detach the events
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();

            Application.Current.Exit -= new ExitEventHandler(this.OnExit);
            Application.Current.FragmentNavigation -= new System.Windows.Navigation.FragmentNavigationEventHandler(this.FragmentNavigation);
            Application.Current.Navigated -= new System.Windows.Navigation.NavigatedEventHandler(this.Navigated);
            Application.Current.Startup -= new StartupEventHandler(this.Startup);
        }

        #region Implementation
        /// <summary>
        /// Track the Application.Startup event
        /// </summary>
        /// <param name="sender">the application</param>
        /// <param name="e">the startup event arguments</param>
        private void Startup(object sender, StartupEventArgs e)
        {
            var logEvent = new AnalyticsEvent()
            {
                Name = "Startup",
                ObjectName = "Application",
                ObjectType = Application.Current.GetType().Name,
            };

            this.Log(logEvent);
        }

        /// <summary>
        /// Track the Application.Navigated event
        /// </summary>
        /// <param name="sender">the application</param>
        /// <param name="e">the navigation event arguments</param>
        private void Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            var logEvent = new AnalyticsEvent()
            {
                ActionValue = e.Uri.ToString(),
                Name = "Navigated",
                ObjectName = "Application",
                ObjectType = Application.Current.GetType().Name,
            };

            this.Log(logEvent);
        }

        /// <summary>
        /// Track the Application.FragmentNavigation event
        /// </summary>
        /// <param name="sender">the application</param>
        /// <param name="e">the Frame Navigation event arguments</param>
        private void FragmentNavigation(object sender, System.Windows.Navigation.FragmentNavigationEventArgs e)
        {
            var logEvent = new AnalyticsEvent()
            {
                Name = "Startup",
                ObjectName = "FragmentNavigation",
                ObjectType = Application.Current.GetType().Name,
                ActionValue = e.Fragment
            };

            this.Log(logEvent);
        }

        /// <summary>
        /// Track the Application.Exit event
        /// </summary>
        /// <param name="sender">the application</param>
        /// <param name="e">the exit event arguments</param>
        private void OnExit(object sender, ExitEventArgs e)
        {
            var logEvent = new AnalyticsEvent()
            {
                Name = "Exit",
                ObjectName = "Application",
                ObjectType = Application.Current.GetType().Name,
                Value = e.ApplicationExitCode
            };

            this.Log(logEvent);
        }
        #endregion
    }
}